﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Windows.Browser;
using System.Xml.Linq;
using System.IO;
using System.Text;
using System.Diagnostics;


namespace SlvPartecipazione
{
    
    public partial class MainPage : UserControl
    {
        #region Proprietà private
        private System.Windows.Threading.DispatcherTimer dt = new System.Windows.Threading.DispatcherTimer();

    //Code to write Event into log                
    
        #endregion

        public enum Stato
        {
            daEseguire, eseguito, corretto, sbagliato
        }

        public static XDocument XDoc;
        Partita p = new Partita();
        List<Brano> lstBrani = new List<Brano>(7);
        List<PulsanteNota> lstPulsanti = new List<PulsanteNota>(7);
        Invito myInvito = new Invito();

        Brano BranoCorrente = null;
        MediaElement MusicElementCorrente = null;


        #region Costruttore
        public MainPage()
        {
            Invoker i_xml = new Invoker();
            i_xml.InvokePartecipantiEvent = true;
            i_xml.DownloadXmlPartecipanti();



            InitializeComponent();

#if DEBUG
            btnDono.Visibility = System.Windows.Visibility.Visible;
#endif
            brano1.Source = new Uri("http://www.sanitelitalia.it/TEST/1.mp3");
            myInvito.LoadMp3();

            Risposta.RispostaCorrettaEvent += new RispostaDelegate(MainPage_RispostaCorretta);
            Risposta.RispostaSbagliataEvent += new RispostaDelegate(MainPage_RispostaSbagliata);

            Invoker.VerificaVittoriaEvent += new VerificaVittoriaDelegate(Invoker_VerificaVittoriaEvent);
            Invoker.DownloadXmlPartecipantiEvent += new DownloadXmlPartecipanti(Invoker_DownloadXmlPartecipantiEvent);

            #region Testo Istruzioni gioco
            txtIstruzioni.Text =
                @"Welcome to Sarabanda!

Come si gioca?
Hai a disposizione 30 secondi per indovinare il titolo di 7 brani della musica italiana e straniera.
Per avviare il gioco basta cliccare sul pulsante “Play” ed il tempo comincerà a scorrere. 

Se pensi di conoscere il titolo del brano che stai ascoltando, premi di nuovo sul pulsante! In questo modo interromperai il tempo e potrai inserire la risposta. 
Non conosci la canzone? Hai a disposizione 2 aiuti per ogni brano che potrai usare cliccando sul pulsante “?”.

Non hai capito il brano anche con gli aiuti? Passa alla canzone successiva premendo di nuovo “Play”.
Naturalmente quando il tempo finisce puoi ricominciare a giocare!

Per rendere il tutto più interessante verranno pubblicate le vostre statistiche che riguardano la partita!

Tutto chiaro? E allora cosa aspetti? Alza il volume, metti le cuffie e...inizia a giocare!

Al termine del gioco, riceverai un premio speciale!
                ";
            #endregion

            this.LayoutRoot.SizeChanged += new SizeChangedEventHandler(LayoutRoot_SizeChanged);

            resetContatore();

            resetTxtSconfitta();

            caricaBrani();

            popolaListaPulsanti();

            Invoker i = new Invoker();
            i.CreaPartita();

            Invoker i_verifica = new Invoker();
            i_verifica.InvokeVerificaVittoria = true;
            i_verifica.VerificaVittoria();

            PlayPause.IsEnabled = false;
        }

        void Invoker_DownloadXmlPartecipantiEvent(string Xml)
        {
            XDoc = XDocument.Parse(Xml);

#if !DEBUG
            if (string.IsNullOrEmpty(Utils.getGUID()))
            {
                HtmlPage.Window.Navigate(new Uri("http://gigi4isa2marriage.appspot.com/errore.html"));
                return;
            }
            else if (string.IsNullOrEmpty(getNomePartecipante(Utils.getGUID())))
            {
                HtmlPage.Window.Navigate(new Uri("http://gigi4isa2marriage.appspot.com/errore.html"));
                return;
            }
#endif

            txtNome.Text = txtNome.Text + getNomePartecipante(Utils.getGUID()) + " !";
        }

        void Invoker_VerificaVittoriaEvent()
        {
            btnDono.Visibility = System.Windows.Visibility.Visible;
            sbLampeggioDono.Begin();
        }
        #endregion

        ColorfulFireworks.ColorfulFireworks _colourfulFirework = null;

        void MainPage_RispostaCorretta()
        {
            setStato(Stato.corretto);
            if (p.isPartitaVinta(lstBrani).Equals(Partita.esitoPartita.vinta))
            {
                Invoker i = new Invoker();
                i.SegnalaVittoria();

                Invoker i1 = new Invoker();
                i1.IncrementaDurata(300 - Convert.ToInt32(ucCircleBar.Contatore.Substring(0, 4).Replace(",", "")));

                // add the controls to the back
                _colourfulFirework = new ColorfulFireworks.ColorfulFireworks();

                LayoutRoot.Children.Insert(0, _colourfulFirework);

                _colourfulFirework.Start();

                PlayPause.IsEnabled = false;
                btnDono.Visibility = System.Windows.Visibility.Visible;
                sbLampeggioDono.Begin();
            }
        }

        void MainPage_RispostaSbagliata()
        {
            setStato(Stato.sbagliato);
            //if (p.isPartitaVinta(lstBrani).Equals(Partita.esitoPartita.persa))
            //{
            //    // RITENTA, SARAI PIU' FORTUNATO!
            //    Finish();
            //}
        }

        

        #region Private methods
        
        private string getNomePartecipante(string GUID)
        {
#if DEBUG
            if (!String.IsNullOrEmpty(GUID) && !GUID.Equals("", StringComparison.InvariantCultureIgnoreCase))
#else
            if (!String.IsNullOrEmpty(GUID) && !GUID.Equals("", StringComparison.InvariantCultureIgnoreCase))
#endif
            {
                IEnumerable<string> searched =
                    from c in XDoc.Elements("PARTECIPANTI").Elements("PARTECIPANTE")
                    where (string)c.Element("GUID") == GUID
                    select c.Element("ALIAS").Value;

                try
                {
                    return searched.First();
                }
                catch (Exception)
                {
                    return string.Empty;
                }
                
            }
            return String.Empty;
        }

        private void getTimeStamp()
        {
            if (HtmlPage.Document.QueryString.ContainsKey("time"))
            {
                string queryStringValue = HtmlPage.Document.QueryString["time"];
                if (queryStringValue.IsTimeStampValid())
                {
                    txtNome.Text = "Timestamp = " + queryStringValue;
                }
                else
                {
                    txtNome.Text = "Timestamp parameter in current URL is wrong.";
                }
            }
        }
        #endregion


        public void setStato(Stato stato)
        {
            BranoCorrente.stato = stato;
            (lstPulsanti.ElementAt(BranoCorrente.indice))._statoPulsante = stato;
            (lstPulsanti.ElementAt(BranoCorrente.indice)).checkStatoPulsante();
        }

        public void popolaListaPulsanti()
        {
            lstPulsanti.Add(pulsante1);
            lstPulsanti.Add(pulsante2);
            lstPulsanti.Add(pulsante3);
            lstPulsanti.Add(pulsante4);
            lstPulsanti.Add(pulsante5);
            lstPulsanti.Add(pulsante6);
            lstPulsanti.Add(pulsante7);
        }

        public void caricaBrani()
        {
            for (int i = 0; i < lstBrani.Capacity; i++)
            {
                Brano b = new Brano();

                switch (lstBrani.Count)
                {
                    case 0:
                        b.assegnaMP3(lstBrani.Count, brano1);
                        break;
                    case 1:
                        b.assegnaMP3(lstBrani.Count, brano2);
                        break;
                    case 2:
                        b.assegnaMP3(lstBrani.Count, brano3);
                        break;
                    case 3:
                        b.assegnaMP3(lstBrani.Count, brano4);
                        break;
                    case 4:
                        b.assegnaMP3(lstBrani.Count, brano5);
                        break;
                    case 5:
                        b.assegnaMP3(lstBrani.Count, brano6);
                        break;
                    case 6:
                        b.assegnaMP3(lstBrani.Count, brano7);
                        break;
                }

                //MediaElement _sound = b.assegnaMP3(lstBrani.Count);
                b.stato = Stato.daEseguire;
                lstBrani.Add(b);

                //this.LayoutRoot.Children.Add(_sound);
            }
        }

        void resetTxtSconfitta()
        {

        }

        void scriviSconfitta()
        {
            //sbLose.Begin();
        }

        void resetContatore()
        {
            ucCircleBar.Contatore = (ucCircleBar.TempoLimiteInMillisecondi / 1000).ToString("00.0") + " sec.";
            ucCircleBar.Value = 0;
        }

        void StopCountdown()
        {
            ucCircleBar.Pause();
        }

        void stopAll()
        {
            p.interrompiBrani(lstBrani);

            foreach (PulsanteNota puls in lstPulsanti)
            {
                puls.sbLampeggioPulsante.Stop();
            }
        }

        public void resetTuttiStatoPulsante()
        {
            foreach (PulsanteNota puls in lstPulsanti)
            {
                // se lo stato è 'corretto', NON viene resettato
                if (!puls._statoPulsante.Equals(MainPage.Stato.corretto))
                {
                    puls._statoPulsante = Stato.daEseguire;
                    puls.checkStatoPulsante();
                }
            }
        }

        public void Finish()
        {
            foreach (PulsanteNota puls in lstPulsanti)
            {
                // se lo stato è 'corretto', NON resetto l'immagine della nota
                if (!puls._statoPulsante.Equals(Stato.corretto))
                    puls.img1.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("/SlvPartecipazione;component/IMG/notaGrigia.png", UriKind.Relative));
            }

            // Interrompe il brano e il lampeggio del pulsante
            stopAll();

            resetContatore();

            p.resetTuttiBraniDaEseguire(lstBrani);
            
            resetTuttiStatoPulsante();

            //se termino il tempo, passo l'indice massimo per far eseguire il primo brano da eseguire
            BranoCorrente = p.getBranoDaEseguire(lstBrani, lstBrani.Capacity-1);

            myButtonImg.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("/SlvPartecipazione;component/IMG/play.png", UriKind.Relative));

            PlayPause.IsEnabled = false;

            sbLose.Completed += (_, a) =>
                {
                    sbTxtLose.Begin();
                };
            sbLose.Begin();

            Invoker i = new Invoker();
            i.IncrementaDurata(300);
        }


        #region Eventi

        private void myMediaElement_DownloadProgressChanged(object sender, RoutedEventArgs e)
        {
            double percentage = ((MediaElement)sender).DownloadProgress * 100;
            string text = (int)Math.Round(percentage, 0) + "%";

            txtDownload.Text = "Download brano " + ((MediaElement)sender).Name.Substring(5) + " di 7";
            txtPerc.Text = text;

            if (percentage == 100)
            {
                
                switch (((MediaElement)sender).Name)
                {
                    case "brano1":
                        brano2.Source = new Uri("http://www.sanitelitalia.it/TEST/2.mp3");
                        break;
                    case "brano2":
                        brano3.Source = new Uri("http://www.sanitelitalia.it/TEST/3.mp3");
                        break;
                    case "brano3":
                        brano4.Source = new Uri("http://www.sanitelitalia.it/TEST/4.mp3");
                        break;
                    case "brano4":
                        brano5.Source = new Uri("http://www.sanitelitalia.it/TEST/5.mp3");
                        break;
                    case "brano5":
                        brano6.Source = new Uri("http://www.sanitelitalia.it/TEST/6.mp3");
                        break;
                    case "brano6":
                        brano7.Source = new Uri("http://www.sanitelitalia.it/TEST/7.mp3");
                        break;
                    case "brano7":
                        txtDownload.Text = "";
                        txtPerc.Text = "";
                        PlayPause.IsEnabled = true;
                        break;
                }
            }
        }

        void _Sound_MediaOpened(object sender, RoutedEventArgs e)
        {
            MediaElement _Sound = sender as MediaElement;
            _Sound.Play();
        }


        private void PlayPause_Click(object sender, RoutedEventArgs e)
        {
            if (BranoCorrente == null)
            {
                BranoCorrente = lstBrani[0];
            }
            else if (!BranoCorrente.stato.Equals(Stato.daEseguire))
            {
                p.resetTuttiBraniDaEseguire(lstBrani);
                BranoCorrente = p.getBranoDaEseguire(lstBrani, BranoCorrente.indice);
            }

            MusicElementCorrente = BranoCorrente.mediaSound;

            switch (MusicElementCorrente.CurrentState)
            {
                case MediaElementState.Playing:
                    stopAll();
                    StopCountdown();

                    setStato(Stato.eseguito);

                    (lstPulsanti.ElementAt(BranoCorrente.indice)).sbLampeggioPulsante.Stop();

                    myButtonImg.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("/SlvPartecipazione;component/IMG/play.png", UriKind.Relative));
                    ucRisposta.Show(BranoCorrente);
                    break;

                case MediaElementState.Paused:
                case MediaElementState.Stopped:
                    ucRisposta.Nascondi();
                    resetTxtSconfitta();
                    (lstPulsanti.ElementAt(BranoCorrente.indice)).sbLampeggioPulsante.Begin();

                    MusicElementCorrente.MediaOpened += new RoutedEventHandler(_Sound_MediaOpened);
                    MusicElementCorrente.Play();

                    ucCircleBar.Start(this);
                    myButtonImg.Source = new System.Windows.Media.Imaging.BitmapImage(new Uri("/SlvPartecipazione;component/IMG/pause.png", UriKind.Relative));
                    break;
            }

        }

        

        private void btnMostraInvito_Click(object sender, RoutedEventArgs e)
        {
            App.Navigate(myInvito);
        }

        private void btnRispondo_Click(object sender, RoutedEventArgs e)
        {
            
        }

        void LayoutRoot_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            Grid g = sender as Grid;
            
            double canvasheight = (g.RowDefinitions.Count > 0) ? g.RowDefinitions[0].ActualHeight : g.ActualHeight;
            double canvaswidth = g.ActualWidth;

            double scaleX = canvaswidth / Wall.Width;
            double scaleY = canvasheight / Wall.Height;

            if (scaleX > scaleY)
                scaleX = scaleY;
            else
                scaleY = scaleX;

            this.WallStretch.ScaleX = scaleX;
            this.WallStretch.ScaleY = scaleY;
            this.WallTranslate.X = (g.ActualWidth - Wall.Width * scaleX) / 2;
            this.UpdateLayout();
        }

        private void btnDono_Click(object sender, RoutedEventArgs e)
        {
            myInvito.getInvitato(Utils.getGUID());
            myInvito.Start();
            App.Navigate(myInvito);
        }
        #endregion
        
        private void txtGameOver_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            Canvas.SetTop(imgLose, -650);
            Canvas.SetTop(txtGameOver, -100);

            PlayPause.IsEnabled = true;

        }
                        
    }
    
}
